package com.stock.core.service.stock;

import com.stock.api.basic.BusinessException;
import com.stock.api.domain.stock.StockCodeBean;
import com.stock.api.service.stock.StockCodeService;
import com.stock.core.persistence.reader.stock.StockCodeReaderMapper;
import com.stock.core.persistence.writer.stock.StockCodeWriterMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>股票代码服务实现</p>
 *
 * @author 张峰 zfvip_it@163.com
 * @createTime: 2016/8/1 13:09
 */
@Service("stockCodeService")
public class StockCodeServiceImpl implements StockCodeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(StockCodeServiceImpl.class);

    @Resource
    private StockCodeWriterMapper stockCodeWriterMapper;

    @Resource
    private StockCodeReaderMapper stockCodeReaderMapper;


    /***
     * 更新股票代码列表
     *
     * @throws Exception
     */
    public int extractStockCode() throws Exception {
        LOGGER.info("开始抓取股票代码列表···");
        int records = -1;
        String htmlContent = getHtmlContent(getUrl());
        if (StringUtils.isNotBlank(htmlContent)) {
            /**根据网页源码解析股票列表*/
            List<StockCodeBean> list = getStockCodeData(htmlContent);

            if (list != null && list.size() > 0) {
                int size = list.size();
                List<StockCodeBean> stockCodeBeanList = new ArrayList<>();
                //清除所有的股票代码列表
                stockCodeWriterMapper.deleteAll();
                for (int i = 0; i < list.size(); i++) {
                    stockCodeBeanList.add(list.get(i));
                    if (i % 400 == 0 || i == size - 1) {
                        records = stockCodeWriterMapper.batchInsertSelective(stockCodeBeanList);
                        stockCodeBeanList.clear();
                    }
                }
            } else {
                LOGGER.error("解析网页数据失败！");
                throw new BusinessException("抓取网页源码失败!");
            }

        } else {
            LOGGER.error("抓取网页源码失败！");
            throw new BusinessException("抓取网页源码失败!");
        }
        LOGGER.info("抓取股票代码列表结束···");
        return records;
    }

    /***
     * 解析网页数据
     *
     * @param htmlContent
     */
    private List<StockCodeBean> getStockCodeData(String htmlContent) {
        //String regx = "[*\\u4E00-\\u9FA5\\sA-ZＡ]{3,7}\\(((002|000|300|600|001)[\\d]{3}|60[\\d]{4})\\)";
        //String regx = "[*\\u4E00-\\u9FA5\\sA-ZＡ]{3,7}\\(([\\d]{6}|60[\\d]{4})\\)";
        String regx = "[shz]{2}([\\d]{6}).html\">[ＲＣ\\-*\\u4E00-\\u9FA5\\sA-ZＡ[\\d]]{2,10}\\((((002|000|300|600)[\\d]{3})|60[\\d]{4})\\)";
        Pattern p = Pattern.compile(regx);
        Matcher macher = p.matcher(htmlContent);
        int num = 0;
        List<StockCodeBean> list = new ArrayList<StockCodeBean>();
        while (macher.find()) {
            StockCodeBean stockCodeBean = new StockCodeBean();
            /**股票代码*/
            stockCodeBean.setStockCode(macher.group().substring(macher.group().length() - 7, macher.group().length() - 1));
            /**股票名称*/
            stockCodeBean.setStockName(macher.group().substring(15, macher.group().length() - 8));
            /**股票类型*/
            stockCodeBean.setStockType(macher.group().substring(0, 2));
            /**创建时间*/
            stockCodeBean.setCreateTime(new Date());

            list.add(stockCodeBean);
            //System.out.println("类型：" + macher.group().substring(0, 2));
            //System.out.println("名称：" + macher.group().substring(15, macher.group().length() - 8));
            //System.out.println("代码：" + macher.group().substring(macher.group().length() - 7, macher.group().length() - 1));
            ++num;
        }
        if (LOGGER.isDebugEnabled())
            LOGGER.debug("抓取代码列表数量：" + num);
        return list;
    }

    /***
     * 获取网页源码
     *
     * @param urlPath
     * @return
     */
    public String getHtmlContent(String urlPath) {
        try {
            URL url = new URL(urlPath);
            URLConnection urlConnection = url.openConnection();
            BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "gbk"));
            String str = "";
            StringBuffer content = new StringBuffer();
            while ((str = br.readLine()) != null) {
                content.append(str);
            }
            br.close();
            return content.toString();
        } catch (Exception e) {
            LOGGER.error("抓取网页源码出现错误", e);
        }
        return null;
    }

    /**
     * 网页地址
     *
     * @return
     */
    public String getUrl() {
        //return "http://bbs.10jqka.com.cn/codelist.html";
        return "http://quote.eastmoney.com/stocklist.html";
    }

    /**
     * 获取所有股票代码列表
     *
     * @return
     */
    public List<StockCodeBean> queryAll() {
        return stockCodeReaderMapper.queryAll();
    }

    /**
     * 根据股票代码获取股票信息
     *
     * @param stockCode
     * @return
     */
    @Cacheable(value = "redisManager", key = "#stockCode + 'stockCode'")
    public StockCodeBean selectByStockCode(String stockCode) {
        return stockCodeReaderMapper.selectByStockCode(stockCode);
    }
}
